import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { Water } from 'three/examples/jsm/objects/Water.js'
import { Sky } from 'three/examples/jsm/objects/Sky.js'
import * as dat from 'dat.gui'


let camera, scene, renderer;
let water, sun, sky, cube
//将cube变真实
let pmremGenerator, renderTarget
let sunParams,gui

initRenderer()
initCamera()
initScene()
initMeshes()
initAxesHelper();
enableControls();
animate();

window.addEventListener("resize", onWindowResize);

function initRenderer(params) {
    renderer = new THREE.WebGLRenderer({ antialias: true })
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(window.innerWidth, window.innerHeight)
    //太阳变小
    renderer.toneMapping = THREE.ACESFilmicToneMapping
    document.body.appendChild(renderer.domElement)

    pmremGenerator = new THREE.PMREMGenerator(renderer)
}

function initCamera(params) {
    camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 20000)
    camera.position.set(30,30,100)
}

function initScene(params) {
    scene = new THREE.Scene()
}

function initMeshes(params) {

    //水和太阳
    sun = new THREE.Vector3(-80,5,-100)
    water = new Water(
        new THREE.PlaneGeometry(10000, 10000),
        {
            waterNormals: new THREE.TextureLoader().load(
                'textures/waternormals.jpg',
                function (texture) {
                    texture.wrapS = texture.wrapT = THREE.RepeatWrapping
                }
            ),
            sunDirection: sun,
            sunColor: 0xffffff,
            waterColor: 0x001e0f
        }
    );
    water.rotation.x = -Math.PI / 2
    scene.add(water)

    //天空
    sky = new Sky();
    sky.scale.setScalar(10000);
    scene.add(sky)
    console.log(sky);

    const skyUniforms = sky.material.uniforms; 
    skyUniforms['turbidity'].value = 10  //浑浊度
    skyUniforms['rayleigh'].value = 2 //锐利度
    skyUniforms['mieCoefficient'].value = 0.005;
    skyUniforms['mieDirectionalG'].value =0.8
  

    sunParams = {
        elevation: 2,//极角
        azimuth:180 //方位角
    }
    updateSun()

    //物体
    let geometry = new THREE.BoxGeometry(30, 30, 30)
    let material = new THREE.MeshStandardMaterial()
    cube = new THREE.Mesh(geometry, material)
    scene.add(cube)
    enableGUI()
}

function enableGUI() { 
    gui = new dat.GUI()
    const folderSun = gui.addFolder('太阳');
    folderSun.add(sunParams, 'elevation', 0, 90, 0.05).onChange(updateSun)
    folderSun.add(sunParams, 'azimuth', -180, 180, 0.1).onChange(updateSun)
    const WaterParams = water.material.uniforms
    const foderwater = gui.addFolder('水')
    foderwater.add(WaterParams.size,'value', 0.1,20,0.1).name('size')
}

function updateSun() { 

    const theta = THREE.MathUtils.degToRad(90 - sunParams.elevation)
    const phi = THREE.MathUtils.radToDeg(sunParams.azimuth)
    sun.setFromSphericalCoords(1, theta, phi)
    
    sky.material.uniforms['sunPosition'].value.copy(sun)
    //物体的反射效果
    if (renderTarget !== undefined) renderTarget.dispose();
    renderTarget = pmremGenerator.fromScene(sky);
    scene.environment = renderTarget.texture

}

function initAxesHelper(params) {
    scene.add(new THREE.AxesHelper(100))
}

function enableControls(params) {
    const controls = new OrbitControls(camera, renderer.domElement)
    // controls.target.set(0, 10, 0)
    controls.update()
}

function onWindowResize(params) {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth,window.innerHeight)
}

function animate(params) {
    requestAnimationFrame(animate)
    render()
}

function render(params) {
    const time = window.performance.now() * 0.001;
    cube.position.y = Math.sin(time) * 20 + 5
    cube.rotation.x = time * 0.5
    cube.rotation.z = time * 0.5
    
    water.material.uniforms['time'].value += 1/60
    renderer.render(scene,camera)
}